#include <vector>
#include <ext/hash_map>
#include <deque>
#include <iostream>
#include <numeric>
#include <algorithm>
#include <list>
#include <string>
#include <cstdlib>
#include <functional>
using std::bind2nd;
#include <algorithm>
using std::equal_to;


#include <boost/algorithm/string.hpp>


#define DEBUG_LEVEL 8
#include <debug_func.h>
#include <print_error.h>
#include <perlutil.h>
#include <ultoa.h>
using std::string;
using std::vector;

#include <gsl_cdf_hypergeometric_P.h>
#include "get_arg.h"

//8888888888888888888888888888888888888888888888888888888888888888888888888888888888888888

//	main

//8888888888888888888888888888888888888888888888888888888888888888888888888888888888888888


int main (int argc, char *argv[])
{
	// we use cout to print progress so flush per call
//	cout.setf(std::ios_base::unitbuf);

	debug_func_cout(5);
//	std::ios::sync_with_stdio(false);

	t_program_args args;
	try
	{
		if (!process_command_line_options(argc, argv, args))
			return 1;
		string line;
		unsigned cnt_lines = 0;
		while (getline(std::cin, line))
		{
			++cnt_lines;
			if (line.empty())
				continue;
			
			vector<string> data;
			boost::split(data, line, bind2nd(equal_to<char>(), '\t'));
			if (data.size() != 5)
				throw std::runtime_error("Wrong number of arguments on line "
										 + ultoa(cnt_lines));
			
			char* end = 0;
			unsigned	sample_hits = strtoul(data[1].c_str(), &end, 10);
			if (data[1].c_str() == end)
				throw std::runtime_error("Invalid number for sample matches on line "
										 + ultoa(cnt_lines));
			unsigned	sample_pop = strtoul(data[2].c_str(), &end, 10);
			if (data[2].c_str() == end)
				throw std::runtime_error("Invalid number for sample population on line "
										 + ultoa(cnt_lines));

			unsigned	total_hits = strtoul(data[3].c_str(), &end, 10);
			if (data[3].c_str() == end)
				throw std::runtime_error("Invalid number for total matches on line "
										 + ultoa(cnt_lines));
			unsigned	total_pop = strtoul(data[4].c_str(), &end, 10);
			if (data[4].c_str() == end)
				throw std::runtime_error("Invalid number for total population on line "
										 + ultoa(cnt_lines));

			if (sample_hits > sample_pop)
				throw std::runtime_error("The number of sample which match ( = " +
										 ultoa(sample_hits) + " ) "
										"has to be smaller than the number of samples ("
										" = " + ultoa(sample_pop) + " ) on line "
										 + ultoa(cnt_lines));
			if (total_hits > total_pop)
				throw std::runtime_error("The number of all items which match ( = " +
										 ultoa(total_hits) + " ) "
										"has to be smaller than the background population size ("
										" = " + ultoa(total_pop) + " ) on line "
										 + ultoa(cnt_lines));
			if (sample_pop > total_pop)
				throw std::runtime_error("The number of items sampled ( = " +
										 ultoa(sample_pop) + " ) "
										"has to be smaller than the total (background) population ("
										" = " + ultoa(total_pop) + " ) on line "
										 + ultoa(cnt_lines));
			std::cout	<< data[0] << "\t"
						<< gsl_cdf_hypergeometric_P (sample_hits, 
													total_hits,
													total_pop - total_hits,
													sample_pop) << "\t";
			// so that calculates greater than or equal
			if (sample_hits > 1)
				--sample_hits;
			std::cout << gsl_cdf_hypergeometric_Q (	sample_hits, 
													total_hits,
													total_pop - total_hits,
													sample_pop) << std::endl;
		}

		args.VERBOSE() << "\n\tAll finished!!\n\n";
	}
	catch(std::exception& e)
	{
		std_print_error(args.CERR(),  e.what());
		return false;
	}
	return 0;
}



